package com.dxy.df.core.model;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dxy.df.constants.ConstStrings;
import com.dxy.df.constants.ErrorEnum;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.Getter;
import lombok.Setter;
import org.springframework.http.HttpStatus;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>class_name: Rs</p>
 * <p>package: com.dxy.df.core.model</p>
 * <p>@author: wangsheng@dxy.cn</p>
 * <p>@date: 2019-07-25 </p>
 **/
@Setter
@Getter
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class Rs<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    private Integer code;

    private String msg;

    private boolean success;

    private T data;

    @JsonIgnore
    private Map<String, Object> map = new HashMap<>();


    public Rs() {
        code = 200;
        msg = ConstStrings.SUCCESS;
        success=true;

    }

    public Rs(T data) {
        code = 200;
        msg = ConstStrings.SUCCESS;
        success=true;
        this.data = data;
    }

    public Rs(int code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;

    }


    public static Rs ok() {
        return new Rs();
    }

    public static Rs ok(int code, String msg) {
        Rs r = new Rs();
        r.setCode(code);
        r.setMsg(msg);
        return r;
    }

    public static Rs ok(int code, String msg,Object data) {
        Rs r = new Rs();
        r.setCode(code);
        r.setMsg(msg);
        r.setData(data);
        return r;
    }


    public static Rs error() {
        return error(HttpStatus.INTERNAL_SERVER_ERROR.value(), "未知异常，请联系管理员");
    }

    public static Rs error(String msg) {
        return error(HttpStatus.INTERNAL_SERVER_ERROR.value(), msg);
    }

    public static Rs error(int code, String msg) {
        Rs r = new Rs();
        r.setCode(code);
        r.setMsg(msg);
        r.setSuccess(false);
        return r;
    }

    public static Rs error(ErrorEnum errorEnum) {
        Rs r = new Rs();
        r.setCode(errorEnum.getCode());
        r.setMsg(errorEnum.getMsg());
        r.setSuccess(false);
        return r;
    }

    public void setMap(String key, Object value) {
        this.map.put(key, value);
    }

    public Rs putData(T data) {
        this.data = data;
        if (null == this.data) {
            this.setCode(10009);
            this.setMsg("数据不存在");
        }
        return this;
    }

    public Rs putData(String key, Object value) {
        setMap(key, value);
        this.putData((T) map);
        return this;
    }

    public Rs<List<T>> putAll(String res, Class<T> beanClass) {
        Rs<List<T>> rs = new Rs<>();
        JSONObject result = JSONObject.parseObject(res);
        if (null == result) {
            rs.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
            rs.setMsg("未知异常，请联系管理员");
            return rs;
        } else if (null != result.getInteger(ConstStrings.CODE)) {
            rs.setCode(result.getInteger(ConstStrings.CODE));
            rs.setMsg(result.getString(ConstStrings.MSG));
            rs.setSuccess(result.getBoolean(ConstStrings.SUCCESS));
            rs.setData(getListObject(result.get(ConstStrings.DATA), beanClass));
        }
        return rs;
    }

    private List<T> getListObject(Object data, Class<T> beanClass) {
        List<T> voList = new ArrayList<>();
        if (data instanceof JSONArray) {
            JSONArray array = (JSONArray) data;
            for (Object item : array) {
                if (item instanceof JSONObject) {
                    JSONObject arrayObject = (JSONObject) item;
                    voList.add(JSONObject.toJavaObject(arrayObject, beanClass));
                }
            }
        }
        return voList;
    }

}
